<?php
/**
 * @version 	$Id: fRouter.class.php 80 2010-03-17 08:21:02Z mylifeisskidrow@gmail.com $
 * @author 		$Author: mylifeisskidrow@gmail.com $
 * @copyright 	Copyright (c) 2010 Luu Trong Hieu. All right reserved.
 * @license 	GNU/GPL see license.php
 */

defined('IN_FLYWHEEL') or die ('Restricted access');

/**
 * Router
 * 	Router xu dung phan tich request tu client chi dinh ra cac controller va action xu dung
 * 
 * @package 	system
 * @subpackage 	application
 *
 */

class fRouter {	
	/**
	 * Culture Info
	 *
	 * @var unknown_type
	 */
	protected $cultureInfo;
	
	/**
	 * Active controller name
	 *
	 * @var string
	 */
	protected $component;
	
	/**
	 * controller name
	 *
	 * @var string
	 */
	protected $controller;
	
	/**
	 * Active method
	 *
	 * @var string
	 */
	protected $action;
	
	/**
	 * Params
	 *
	 * @var array
	 */
	protected $params;
	
	/**
	 * URL
	 *
	 * @var string
	 */
	protected $url;
	
	/**
	 * Base Url
	 *
	 * @var string
	 */
	protected $baseUrl;
	
	/**
	 * Routing Configs
	 *
	 * @var array
	 */
	protected $configs = array();
	
	public function __construct() {
		$this->getConfig();
		$this->url = $url = $this->getPathInfo();
		if ($this->configs['friendly_url'] == 1) {
			$this->parseUrl($url);
			$this->component = ($this->component == null) ? $this->configs['default']['component']:$this->component;
			$this->action = ($this->action == null) ? $this->configs['default']['action']:$this->action;
			$this->cultureInfo = ($this->cultureInfo == null)? $this->configs['default']['culture_info']: $this->cultureInfo;
			if ($this->controller == null) $this->controller = $this->component;
		}
		else {			
			$this->controller = $this->component = fFactory::getRequest()->
								get('com', fFilter::TYPE_STRING, $this->configs['default']['component']);
			$this->action = fFactory::getRequest()->
								get('act', fFilter::TYPE_STRING, $this->configs['default']['action']);
			$this->cultureInfo = fFactory::getRequest()->
								get('culture', fFilter::TYPE_STRING, $this->configs['default']['culture_info']);
			if (isset($this->configs[$this->component])) {
				$this->controller = $this->configs[$this->component]['controller'];
				if (isset($this->configs[$this->component]['action'])) {
					$this->action = $this->configs[$this->component]['action'];
				}
			}	
		}		
		$this->baseUrl = (($_SERVER['HTTPS'] == 'on')? 'https://':'http://') 
							.str_replace('index.php', '', $_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME']);				
		if ($this->action == null) $this->action = 'default';	
	}
	
	/**
	 * Get Config
	 * 
	 * @return 	void
	 * @throws	fConfigException if file not exist 
	 *
	 */
	private function getConfig() {
		if (!fConfig::has(null, 'routing')) {
			fConfig::load(_APP_CONFIGURATION_PATH_.'routing.ini', 'routing');
		}
		//Else load from project routing config
		$this->configs  = fConfig::getConfigByNamespace('routing');						
	}
	
	/**
	 * Get Controller
	 *
	 * @return string
	 */
	public function getComponentName() {
		return $this->component;
	}
	
	/**
	 * Get Controller
	 * 	ten controller
	 *
	 * @return string
	 */
	public function getController() {
		return $this->controller;			
	}
	
	/**
	 * Get Method
	 *
	 * @return string
	 */
	public function getAction() {
		return $this->action;
	}
	
	/**
	 * Get Base Url
	 *
	 * @return string
	 */
	public function getBaseUrl() {
		return $this->baseUrl;
	}
	
	/**
	 * Get Path Info
	 * 	get URL
	 * 
	 * @return 	string
	 *
	 */
	public function getPathInfo() {
		if (isset($_SERVER['PATH_INFO']) && ($_SERVER['PATH_INFO'] != '')) {
			$pathInfo = $_SERVER['PATH_INFO'];
		}
		else {
			$pathInfo = preg_replace('/^'.preg_quote($_SERVER['SCRIPT_NAME'], '/').'/', '', $_SERVER['REQUEST_URI']);
			$pathInfo = preg_replace('/^'.preg_quote(preg_replace('#/[^/]+$#', '', $_SERVER['SCRIPT_NAME']), '/').'/', '', $pathInfo);                
	        $pathInfo = preg_replace('/\??'.preg_quote($_SERVER['QUERY_STRING'], '/').'$/', '', $pathInfo);
	        if ($pathInfo == '') $pathInfo = '/';			
		}
		
        if (isset($this->configs['url_suffix']) && $this->configs['url_suffix'] != '') {        	
        	$pathInfo = str_replace($this->configs['url_suffix'], '', $pathInfo);
        }
		
		return $pathInfo;
	}
	
	/**
	 * Get Culture Info
	 *
	 * @return string
	 */
	public function getCultureInfo() {
		return $this->cultureInfo;
	}
	
	/**
	 * Parse URL
	 *
	 * @param string $url
	 */
	public function parseUrl($url) {		
		if (!isset($this->configs['url_structure']) || $this->configs['url_structure'] == '') {
			throw new ConfigException('Not found define of URL structure in config file!');	
		}
		$regex = '';
		$urlStructure = $this->configs['url_structure'];
		$urlStructure = explode('/', $urlStructure);
		$size = sizeof(explode('/', $url));
		array_splice($urlStructure, $size - 1);
		
		if (end($urlStructure) == '*') { // Neu ki tu cuoi cung danh dau *
			array_pop($urlStructure);
			$regex = "(?:(?:/(?P<_star>.*))?)?";
		}
				
		for ($i = 0, $loop = sizeof($urlStructure); $i < $loop; ++$i) {
			if (($urlStructure[$i][0] == '<') && ($urlStructure[$i][strlen($urlStructure[$i])-1] == '>')) {				
				$urlStructure[$i] = '(?P' . $urlStructure[$i] .'[^/\.]+)';										
			}			
		}
		
		$regex = "#^/". implode("/", $urlStructure) . $regex . "$#x";				
		if (!preg_match($regex, $url, $matches)) {
			return false;
		}
		
		$this->component = $matches['component'];
				
		if (isset($this->configs[$this->component])) {
			$this->controller = $this->configs[$this->component]['controller'];
			if (isset($this->configs[$this->component]['action'])) {
				$this->action = $this->configs[$this->component]['action'];
			}
		}
		else {
			$this->controller = $this->component;
			$this->action = $matches['action'];
		}		
		
		$this->params = $matches['_star'];
		$this->cultureInfo = $matches['culture'];
	}
}